package route

import (
	"github.com/gin-contrib/cors"
	"github.com/gin-gonic/gin"
	"go-chain-api/api"
	"go-chain-api/utils"
	"net/http"
	"strconv"
	"strings"
)

// PaginationValidator 校验分页参数
func PaginationValidator() gin.HandlerFunc {
	return func(c *gin.Context) {
		pageStr := c.Query("pageIndex")
		perPageStr := c.Query("pageSize")

		language := c.Request.Header.Get("language")
		if pageStr == "" || perPageStr == "" {
			response := utils.GetResponse(nil, utils.ParamNotNull, nil, language)
			c.JSON(http.StatusBadRequest, response)
			c.Abort()
			return
		}

		page, err := strconv.Atoi(pageStr)
		if err != nil || page <= 0 {
			response := utils.GetResponse(nil, utils.PageParamInvalid, nil, language)
			c.JSON(http.StatusBadRequest, response)
			c.Abort()
			return
		}

		perPage, err := strconv.Atoi(perPageStr)
		if err != nil || perPage <= 0 {
			response := utils.GetResponse(nil, utils.PageParamInvalid, nil, language)
			c.JSON(http.StatusBadRequest, response)
			c.Abort()
			return
		}

		c.Set("pageIndex", uint((page-1)*perPage))
		c.Set("pageSize", uint(perPage))
		c.Next()
	}
}

// HeaderValidator 检验header
func HeaderValidator() gin.HandlerFunc {
	return func(c *gin.Context) {
		language := c.Request.Header.Get("language")
		if language == "" {
			language = "zh-tw"
		}
		chainName := c.Request.Header.Get("chain-name")
		if chainName == "" {
			response := utils.GetResponse(nil, utils.MissChainName, nil, language)
			c.JSON(http.StatusOK, response)
			c.Abort()
			return
		}

		chainId := c.Request.Header.Get("chain-id")
		if chainId == "" {
			response := utils.GetResponse(nil, utils.MissChainId, nil, language)
			c.JSON(http.StatusOK, response)
			c.Abort()
			return
		}

		chainUint, err := strconv.ParseUint(chainId, 10, 0)
		if err != nil {
			response := utils.GetResponse(nil, utils.ParseDataError, nil, language)
			c.JSON(http.StatusOK, response)
			c.Abort()
			return
		}

		c.Set("chainName", strings.ToUpper(chainName))
		c.Set("chainId", uint(chainUint))
		c.Set("language", strings.ToUpper(language))
		c.Next()
	}
}

// RegisterRoute 注册路由
func RegisterRoute() *gin.Engine {
	router := gin.Default()
	// 允许所有来源、方法、头部
	routerConfig := cors.DefaultConfig()
	routerConfig.AllowAllOrigins = true
	routerConfig.AllowMethods = []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"}
	routerConfig.AllowHeaders = []string{"*"}

	// 区块链浏览器
	blockApi := api.Block{}

	// 添加到 gin 路由
	router.Use(cors.New(routerConfig))
	//router.Use(RecoveryMiddleware())
	v1 := router.Group("/api/v1", HeaderValidator())
	// 获取最近出块信息
	v1.GET("/getBlockLast20", blockApi.GetLastBlocks)
	// 获取区块列表分页
	v1.GET("/getBlockByPage", PaginationValidator(), blockApi.GetBlockByPage)
	// 根据区块号获取区块信息
	v1.GET("/getBlockByNumber", blockApi.GetBlockByNumber)
	// 获取最近的交易信息
	v1.GET("/getTxRecords", PaginationValidator(), blockApi.GetTxRecords)
	// 获取交易信息
	v1.GET("/getTxByHash", blockApi.GetTxByHash)
	// 根据地址查询交易记录
	v1.GET("/getTxByAddress", PaginationValidator(), blockApi.GetTxByAddress)
	// 查询代币转账记录
	v1.GET("/getTokensRecords", PaginationValidator(), blockApi.GetTokensRecords)
	// 根据代币地址查询持有人数
	v1.GET("/getTokenHolders", blockApi.GetTokenHolders)
	// 根据代币地址查询总转账数
	v1.GET("/getTokenTransferCount", blockApi.GetTokenTransferCount)
	// 根据代币地址查询总转账额
	v1.GET("/getTokenTransferAmount", blockApi.GetTokenTransferAmount)
	// 查询最少的手续费
	v1.GET("/getMinerFee", blockApi.GetMinerFee)
	// 查询手续费总数
	v1.GET("/getFeeTotal", blockApi.GetFeeTotal)
	// 获取代币列表
	v1.GET("/getTokenList", blockApi.GetTokenList)
	// 获取余额
	v1.GET("/getBalance", blockApi.GetBalance)
	//判断地址是不是合约
	v1.GET("/isContractAddress", blockApi.IsContractAddress)
	//新增兑换申请
	v1.POST("/createChainApply", blockApi.Create)
	//查询兑换申请
	v1.GET("/getChainApplyList", blockApi.List)
	//获取代币列表
	v1.GET("/getChainTokenList", blockApi.TokenList)
	//获取链列表
	v1.GET("/getApiList", blockApi.ApiList)
	//获取比例
	v1.GET("/getRate", blockApi.GetRate)
	//合约搜索
	v1.GET("/getTokenInfo", blockApi.GetTokenInfo)
	//根据地址查询交易记录(私链)
	v1.GET("/getRecordByAddress", PaginationValidator(), blockApi.GetRecordByAddress)
	//获取代币的当前价格
	v1.GET("/getPrice", blockApi.GetPrice)
	//根据地址查询买入卖出(公共链)
	v1.GET("/getTransferRecord", PaginationValidator(), blockApi.GetTransferRecord)
	//查询底池监听列表
	v1.GET("/swapList", blockApi.SwapList)
	//获取k线历史数据
	v1.GET("/klineData", blockApi.KlineData)
	//获取底池列表
	v1.GET("/poolList", blockApi.PoolList)
	//获取底池交易列表
	v1.GET("/poolTradeList", PaginationValidator(), blockApi.PoolTradeList)
	//底池信息
	v1.GET("/poolInfo", blockApi.PoolInfo)
	//获取Trx链的币价
	v1.GET("/getTrxPrice", blockApi.GetTrxPrice)
	//获取底池的代币信息
	v1.GET("/getToken", blockApi.GetToken)
	//24小时的数据
	v1.GET("/get24HourData", blockApi.Get24HourData)
	//加池撤池列表
	v1.GET("/poolRecordList", PaginationValidator(), blockApi.PoolRecordList)
	//获取汇率
	v1.GET("/getExchangeRate", blockApi.GetExchangeRate)

	return router
}
